package com.etl.aspect;

import com.etl.cache.TokenCache;
import com.etl.constants.CommonConstant;
import com.etl.constants.UserSession;
import com.etl.enums.ResultEnum;
import com.etl.exception.GlobalException;
import com.etl.util.CommonUntil;
import com.etl.util.CookieUtil;
import com.etl.util.RequestUtil;
import com.etl.model.rev.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

/**
 * @author chaixuhong
 * @apiNote 【AOP】接口请求url、参数、请求时间记录日志
 * @date 2019-08-12
 */
@Component
@Aspect
@Slf4j
public class AuthorizeAspect {

    private static final long SLOW_SQL_TIME = 3000;
    @Value("${spring.profiles.active}")
    private String environment;

    @Autowired
    private TokenCache tokenCache;

    @Pointcut("execution(public * com.etl.controller.*.*(..))   && !execution(public * com.etl.controller.LoginController.*(..)))")
    public void verify() {
    }

    /**
     * 【切点】请求前拦截与记录
     */
    @Before("verify()")
    public void doVerify() {
        long reqBegin = System.currentTimeMillis();
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        // 记录请求开始时间
        request.setAttribute("reqBegin", reqBegin);
        /**
         * 从cookie中获取用户登录状态
         */
        Cookie cookie = CookieUtil.get(request, CommonConstant.COOKIE_KEY);
        if (cookie != null) {
            String tokenKey = cookie.getValue();
            LoginUser loginUser = tokenCache.getToken(tokenKey);
            if (loginUser == null) {
               throw new GlobalException(ResultEnum.COOKIE_MISSING);
            }
            UserSession.setUser(loginUser);
        } else {
            throw new GlobalException(ResultEnum.COOKIE_MISSING);
        }
    }

    /**
     * 【切点】请求后拦截与记录
     */
    @After("verify()")
    public void afterVerify() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        Long requestTime = (Long) request.getAttribute("reqBegin");
        long responseTime = System.currentTimeMillis() - requestTime;
        log.info(String.format("接口请求耗时:%s毫秒", responseTime));
        if (responseTime >= SLOW_SQL_TIME) {
            log.warn("【请求时间大于3秒】：used time={},path={}", responseTime, CommonUntil.getLogReplace(RequestUtil.getRequestUrl(request)));
        }
        UserSession.remove();
    }




}
